package com.yang.modules.common.lock.impl;

import com.yang.modules.common.lock.LockClient;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.stereotype.Component;


import java.util.function.Supplier;

/**
 * 分布式锁
 * @author Billyang
 * @date 2024/8/5 15:22
 */
@Component
public class RedissonLockClient implements LockClient {

    private RedissonClient redisson = null;

    public RedissonLockClient(RedisProperties redisProperties) {  //RedisProperties会自动注入进来
        Config config = new Config();
        String address = "redis://" + redisProperties.getHost() + ":" + redisProperties.getPort();

        SingleServerConfig serverConfig = config.useSingleServer().setAddress(address)
                .setConnectTimeout((int) redisProperties.getTimeout().toMillis())
                .setDatabase(redisProperties.getDatabase());
        if (StringUtils.isNotBlank(redisProperties.getPassword())) {
            serverConfig.setPassword(redisProperties.getPassword());
        }
        this.redisson = Redisson.create(config);
    }

    @Override
    public <V> V doInLock(String name, Supplier<V> supplier) {
        RLock lock = redisson.getLock(name);
        try {
            lock.lock();
            return supplier.get();
        } catch (Exception e) {
            throw e;
        } finally {
            lock.unlock();
        }
    }
}
